import { isObject, cloneDeep, debounce } from 'lodash-es';

import { ElLoading } from 'element-plus';
import type { LoadingInstance } from 'element-plus/es/components/loading/src/loading.d';

let needLoadingRequestCount = 0;
let loadingInstance: LoadingInstance | null = null;

function startLoading(message = '') {
  loadingInstance = ElLoading.service({
    text: message,
  });
}

function endLoading() {
  if (loadingInstance) {
    loadingInstance.close();
  }
  loadingInstance = null;
}

function tryCloseLoading() {
  if (needLoadingRequestCount === 0) {
    endLoading();
  }
}

export function showFullScreenLoading(message = ''): void {
  if (needLoadingRequestCount === 0) {
    startLoading(message);
  }
  needLoadingRequestCount += 1;
}

export function hideFullScreenLoading(): void {
  if (needLoadingRequestCount <= 0) {
    return;
  }
  needLoadingRequestCount -= 1;
  if (needLoadingRequestCount === 0) {
    debounce(tryCloseLoading, 300)();
  }
}

export function isEmpty(val: any): boolean {
  return val === null || val === '' || val === undefined;
}

export const deepDeleteEmptyValue = <T extends Record<string, any>>(obj: T) => {
  if (!isObject(obj)) return obj;

  const result = cloneDeep(obj);

  for (const key in result) {
    if (!Reflect.has(result, key)) continue;

    const value = result[key];

    if (isObject(value)) {
      result[key] = deepDeleteEmptyValue(value);
      continue;
    }
    if (isEmpty(value)) {
      Reflect.deleteProperty(result, key);
    }
  }
  return result;
};
